package com.xh.bussiness.course.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.course.bean.dto.*;
import com.xh.bussiness.course.bean.request.CourseIndexRequest;
import com.xh.bussiness.course.bean.request.CourseRequest;
import com.xh.bussiness.course.bean.request.PrepareLessonsInfoRequrst;
import com.xh.bussiness.course.dao.CourseIndexMapper;
import com.xh.bussiness.course.model.Course;
import com.xh.bussiness.course.model.CourseChapter;
import com.xh.bussiness.course.model.CourseIndex;
import com.xh.bussiness.course.model.PrepareLesson;
import com.xh.bussiness.course.service.*;
import com.xh.bussiness.resource.bean.dto.MaterialDto;
import com.xh.bussiness.resource.bean.request.MaterialCourseIndexRequest;
import com.xh.bussiness.resource.model.Material;
import com.xh.bussiness.resource.model.MaterialCourseIndex;
import com.xh.bussiness.resource.model.PaperCourseIndex;
import com.xh.bussiness.resource.service.IMaterialCourseIndexService;
import com.xh.bussiness.resource.service.IMaterialService;
import com.xh.bussiness.resource.service.IPaperCourseIndexService;
import com.xh.bussiness.system.model.Teacher;
import com.xh.bussiness.system.service.ITeacherService;
import com.xh.bussiness.tiku.bean.request.BookChapterRequest;
import com.xh.bussiness.tiku.bean.request.PaperQueryRequest;
import com.xh.bussiness.tiku.model.Paper;
import com.xh.bussiness.tiku.service.IBookChapterService;
import com.xh.bussiness.tiku.service.IPaperService;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.core.util.StringUtils;
import com.xh.core.util.UserUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service
public class CourseIndexServiceImpl extends BaseServiceImpl<CourseIndexMapper, CourseIndex> implements ICourseIndexService {

    @Autowired
    private ICourseService courseService;
    @Autowired
    private ICourseChapterService courseChapterService;
    @Autowired
    private IBookChapterService bookChapterService;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private IPrepareLessonService prepareLessonService;
    @Autowired
    private IMaterialCourseIndexService materialCourseIndexService;
    @Autowired
    private IMaterialService materialService;
    @Autowired
    private IPaperService paperService;
    @Autowired
    private IPaperCourseIndexService paperCourseIndexService;
    @Autowired
    private IPrepareUserConfigService prepareUserConfigService;

    @Override
    public List query(CourseIndexRequest bean) {
        String currentUserId = UserUtils.getCurrentUserId();
        QueryWrapper qw = new QueryWrapper<CourseIndex>();
        //拼装条件
        qw = prepareParams(bean, qw);
        if (!StringUtils.isEmpty(bean.getCourseId())) {
            qw.eq("course_id", bean.getCourseId());
        }
        qw.orderByAsc("order_no");
        List<CourseIndex> list = super.queryByCondition(qw);
        String configStr = prepareUserConfigService.getUserPrepareConfig(currentUserId, bean.getCourseId());
        Integer directTeaching = 0;
        if(StringUtils.isNotEmpty(configStr)){
            JSONObject config = JSON.parseObject(configStr);
            directTeaching = config.getInteger("directTeaching");
        }
        List<CourseIndexDto> result = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            CourseIndex courseIndex = list.get(i);
            CourseIndexDto courseIndexDto = new CourseIndexDto();
            courseIndexDto.setDirectTeaching(directTeaching);
            BeanUtils.copyProperties(courseIndex, courseIndexDto);
            //查询当前老师是否对该课次进行备课
            PrepareLesson prepareLesson = prepareLessonService.queryByUserId(currentUserId, bean.getCourseId(), courseIndex.getId());
            if (prepareLesson == null) {
                //未备课
                courseIndexDto.setLessonStatus(0);
            } else {
                courseIndexDto.setLessonStatus(prepareLesson.getCheckStatus());
            }
            // 我感觉没啥用，先注掉了 JQM
//            QueryWrapper<CourseChapter> chapterQueryWrapper = new QueryWrapper<>();
//            chapterQueryWrapper.eq("course_index_id", courseIndex.getId());
//            List<CourseChapter> courseChapters = courseChapterService.queryByCondition(chapterQueryWrapper);
//            if (courseChapters.size() > 0) {
//                String[] chapters = courseChapters.stream().map(CourseChapter::getChapterId).toArray(String[]::new);
//                BookChapterRequest bookChapterRequest = new BookChapterRequest();
//                bookChapterRequest.setIds(chapters);
//                List chapterList = bookChapterService.queryBookChapter(bookChapterRequest);
//                courseIndexDto.setHasChapters(chapterList);
//            }
            result.add(courseIndexDto);
        }

        return result;
    }

    @Override
    @Transactional
    public boolean add(CourseIndexRequest bean) {
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(bean, courseIndex);
        return this.insert(courseIndex);
    }

    @Override
    @Transactional
    public boolean modify(CourseIndexRequest bean) {
        CourseIndex courseIndex = this.getById(bean.getId());
        if (null == courseIndex) {
            return false;
        }
        getModifyData(bean, courseIndex);
        return this.update(courseIndex);
    }

    @Override
    @Transactional
    public String batchSave(List<CourseIndexRequest> courseIndexRequestList) {
        if (CollectionUtils.isEmpty(courseIndexRequestList)) {
            return "数据不存在";
        }
        //删除原来的课次信息
        String courseId = courseIndexRequestList.get(0).getCourseId();
        QueryWrapper<CourseIndex> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", courseId);
        this.deleteByCondition(queryWrapper);
        int i = 0;
        for (CourseIndexRequest courseIndexRequest : courseIndexRequestList) {
            CourseIndex courseIndex = new CourseIndex();
            courseIndex.setOrderNo(++i);
            BeanUtils.copyProperties(courseIndexRequest, courseIndex);
            this.dao.insert(courseIndex);
        }
        // 更新课次数
        Course course = courseService.getById(courseId);
        course.setCourseIndexNum(courseIndexRequestList.size());
        courseService.update(course);
        return "保存成功";
    }

    @Override
    @Transactional
    public String batchUpdateCourseIndex(List<CourseIndexRequest> courseIndexRequestList) {
        if (CollectionUtils.isEmpty(courseIndexRequestList)) {
            return "数据不存在";
        }
        String courseId = courseIndexRequestList.get(0).getCourseId();
        QueryWrapper<CourseIndex> qw = new QueryWrapper<>();
        qw.eq("course_id", courseId);
        List<CourseIndex> courseIndices = super.queryByCondition(qw);
        for (int i = 0; i < courseIndexRequestList.size(); i++) {
            CourseIndexRequest courseIndexRequest = courseIndexRequestList.get(i);
            CourseIndex courseIndex = this.getById(courseIndexRequest.getId());
            for (CourseIndex index : courseIndices) {
                if (index.getId().equals(courseIndex.getId())) {
                    courseIndices.remove(index);
                    break;
                }
            }
            getModifyData(courseIndexRequest, courseIndex);
            courseIndex.setOrderNo(i + 1);
            this.dao.updateById(courseIndex);
        }
        // 删除多余的课次
        for (CourseIndex courseIndex : courseIndices) {
            super.delete(courseIndex.getId());
        }

        // 修改课程的课次数
        Course course = courseService.getById(courseId);
        course.setCourseIndexNum(courseIndexRequestList.size());
        courseService.update(course);
        return null;
    }

    @Override
    public CourseDto queryOne(String id) {

        CourseDto courseDto = new CourseDto();
        CourseIndex courseIndex = this.dao.selectById(id);
        if (null == courseIndex) {
            return courseDto;
        }
        String courseId = courseIndex.getCourseId();
        CourseRequest courseRequest = new CourseRequest();
        courseRequest.setId(courseId);
        courseDto = courseService.queryOne(courseRequest);
        if (null != courseDto) {
            courseDto.setCourseIndexId(courseIndex.getId());
            courseDto.setCourseIndexName(courseIndex.getCourseIndexName());
            courseDto.setLastSaveDate(courseIndex.getLastSaveDate());
            courseDto.setLessonStatus(courseIndex.getLessonStatus());
        }

        return courseDto;
    }

    private void getModifyData(CourseIndexRequest courseIndexRequest, CourseIndex courseIndex) {
        if (!StringUtils.isEmpty(courseIndexRequest.getCourseIndexName())) {
            courseIndex.setCourseIndexName(courseIndexRequest.getCourseIndexName());
        }
        if (null != courseIndexRequest.getOrderNo()) {
            courseIndex.setOrderNo(courseIndexRequest.getOrderNo());
        }
        if (null != courseIndexRequest.getLessonStatus()) {
            courseIndex.setLessonStatus(courseIndexRequest.getLessonStatus());
        }
    }

    // 备课排名
    @Override
    public List<PrepareLessonsInfoDto> prepareLessonsRank(Date beginQueryTime, Date endQueryTime, int limit) {
        PrepareLessonsInfoRequrst bean = new PrepareLessonsInfoRequrst();
        bean.setBeginQueryTime(beginQueryTime);
        bean.setEndQueryTime(endQueryTime);
        bean.setLimit(limit);
        // 备课排名
        List<PrepareLessonsInfoDto> prepareLessonsRank = this.dao.prepareLessonsRank(bean);
        // 如果不够limit,随便添加几个老师
        if (prepareLessonsRank.size() < 3) {
            int extraSize = 3 - prepareLessonsRank.size();
            QueryWrapper<Teacher> qw = new QueryWrapper<>();
            qw.notIn("user_id", prepareLessonsRank.stream().map(PrepareLessonsInfoDto::getUserId).collect(Collectors.toList()));
            qw.last(String.format("limit %d", extraSize));
            List<Teacher> teachers = teacherService.selectList(qw, Teacher.class);
            List<PrepareLessonsInfoDto> extra = teachers.stream().map(teacher -> {
                PrepareLessonsInfoDto item = new PrepareLessonsInfoDto();
                item.setUserId(teacher.getUserId());
                item.setUsername(teacher.getName());
                return item;
            }).collect(Collectors.toList());
            prepareLessonsRank.addAll(extra);
        }
        // 如果不够limit,随便填充几个空list
        if (prepareLessonsRank.size() < 3) {
            int extraSize = 3 - prepareLessonsRank.size();
            for (int i = 0; i < extraSize; i++) {
                prepareLessonsRank.add(new PrepareLessonsInfoDto());
            }
        }
        return prepareLessonsRank;
    }

    // 备课排名（我的排名）
    @Override
    public int myPrepareLessonsRank(Date beginQueryTime, Date endQueryTime, String userId) {
        // 我的备课信息
        PrepareLessonsInfoRequrst bean = new PrepareLessonsInfoRequrst();
        bean.setUserId(userId);
        bean.setBeginQueryTime(beginQueryTime);
        bean.setEndQueryTime(endQueryTime);
        PrepareLessonsInfoDto info = this.dao.myPrepareLessonsInfo(bean);


        // 备课排名（我的排名）
        bean = new PrepareLessonsInfoRequrst();
        bean.setBeginQueryTime(beginQueryTime);
        bean.setEndQueryTime(endQueryTime);
        if (null != info) {
            bean.setNumber(info.getNumber());
            bean.setCreateTime(info.getCreateTime());
        }
        return this.dao.myPrepareLessonsRank(bean);
    }

    @Override
    public boolean modifyCourseIndexUpOrDown(String courseIndexId, Integer moveType) {
        CourseIndex courseIndex = this.dao.selectById(courseIndexId);
        if (courseIndex == null) {
            return false;
        }
        CourseIndex siblingCourseIndex = getSiblingCourseIndex(courseIndex.getCourseId(), courseIndex.getOrderNo(), moveType);

        Integer oldOrderNo = courseIndex.getOrderNo();
        if (siblingCourseIndex != null) {
            courseIndex.setOrderNo(siblingCourseIndex.getOrderNo());
            siblingCourseIndex.setOrderNo(oldOrderNo);

            this.update(courseIndex);
            this.update(siblingCourseIndex);
        }
        return true;
    }

    @Override
    public boolean deleteCourseIndex(String courseIndexId) {
        CourseIndex courseIndex = this.getById(courseIndexId);
        this.delete(courseIndexId);
        QueryWrapper<CourseIndex> qw = new QueryWrapper<>();
        qw.eq("course_id", courseIndex.getCourseId());

        Integer count = this.selectCount(qw);
        Course course = courseService.getById(courseIndex.getCourseId());
        course.setCourseIndexNum(count);
        courseService.update(course);

        return true;
    }

    @Override
    public boolean batchDeleteCourseIndex(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        for (String id : ids) {
            deleteCourseIndex(id);
        }
        return true;
    }

    @Override
    public String deleteMaterial(Integer type, String courseIndexId, String materialId) {
        if(type == 1){
            MaterialCourseIndexRequest bean = new MaterialCourseIndexRequest();
            bean.setCourseIndexId(courseIndexId);
            bean.setMaterialId(materialId);
            materialCourseIndexService.delete(bean);
        }else{
            QueryWrapper<PaperCourseIndex> qw = new QueryWrapper<>();
            qw.eq("course_index_id",courseIndexId);
            qw.eq("paper_id",materialId);
            paperCourseIndexService.delete(qw);
        }
        return null;
    }

    @Override
    public String batchModify(List<CourseIndexRequest> bean) {
        int i = 0;
        for (CourseIndexRequest courseIndexRequest : bean) {
            CourseIndex courseIndex = new CourseIndex();
            BeanUtils.copyProperties(courseIndexRequest, courseIndex);
            courseIndex.setOrderNo(++i);
            if (courseIndex.getId() == null) {
                super.insert(courseIndex);
                if (CollectionUtils.isEmpty(courseIndexRequest.getChapterIds())) {
                    continue;
                }
                // 查询该课次对应章节绑定的资料
                List<Material> materials = materialService.queryMaterialByChapterId(courseIndexRequest.getChapterIds().get(0));
                if (CollectionUtils.isEmpty(materials)) {
                    continue;
                }
                for (Material material : materials) {
                    MaterialCourseIndex materialCourseIndex = new MaterialCourseIndex();
                    materialCourseIndex.setMaterialId(material.getId());
                    materialCourseIndex.setCourseIndexId(courseIndex.getId());
                    materialCourseIndexService.insert(materialCourseIndex);
                }
            } else {
                super.update(courseIndex);
            }
        }
        if (!bean.isEmpty()) {
            Course course = courseService.getById(bean.get(0).getCourseId());
            course.setCourseIndexNum(bean.size());
            courseService.update(course);
        }
        return null;
    }

    @Override
    public Map<String,Object> queryMaterials(String courseIndexId) {
        MaterialCourseIndexRequest bean = new MaterialCourseIndexRequest();
        bean.setCourseIndexId(courseIndexId);
        // 查询试卷
        List<Paper> papers = null;
        List<PaperCourseIndex> paperCourseIndices = paperCourseIndexService.queryByCourseIndexId(courseIndexId);
        if(CollectionUtils.isEmpty(paperCourseIndices)){
            papers = new ArrayList<>();
        }else {
            PaperQueryRequest paperBean = new PaperQueryRequest();
            paperBean.setIds(paperCourseIndices.stream().map(PaperCourseIndex :: getPaperId).collect(Collectors.toList()).toArray(new String[paperCourseIndices.size()]));
            papers = paperService.queryPaper(paperBean);
        }
        List<MaterialDto> materialDtos = materialCourseIndexService.queryMaterialByCourseIndex(bean);
        Map<String, Object> result = new HashMap<>();
        result.put("papers",papers);
        result.put("materials",materialDtos);
        return result;
    }

    @Override
    public String addMaterials(String courseIndexId, String materialId) {
        MaterialCourseIndex materialCourseIndex = new MaterialCourseIndex();
        materialCourseIndex.setCourseIndexId(courseIndexId);
        materialCourseIndex.setMaterialId(materialId);
        materialCourseIndexService.insert(materialCourseIndex);
        return "添加成功";
    }

    @Override
    public String addPaper(String courseIndexId, String paperId) {
        PaperCourseIndex paperCourseIndex = new PaperCourseIndex();
        paperCourseIndex.setPaperId(paperId);
        paperCourseIndex.setCourseIndexId(courseIndexId);
        paperCourseIndexService.insert(paperCourseIndex);
        return "添加成功";
    }

    @Override
    public boolean clearAllMaterial(String courseIndexId) {
        materialCourseIndexService.deleteByCourseIndex(courseIndexId);
        paperCourseIndexService.deleteByCourseIndex(courseIndexId);
        return true;
    }

    @Override
    public String clearAll(String courseId) {
        QueryWrapper<CourseIndex> qw = new QueryWrapper<>();
        qw.eq("course_id", courseId);
        super.deleteByCondition(qw);
        Course course = courseService.getById(courseId);
        course.setCourseIndexNum(0);
        courseService.update(course);
        return "清除成功";
    }

    /**
     * 获取课次相邻节点
     *
     * @param courseId
     * @param moveType
     * @return
     */
    private CourseIndex getSiblingCourseIndex(String courseId, Integer orderNo, Integer moveType) {
        QueryWrapper<CourseIndex> qw = new QueryWrapper<>();
        qw.eq("course_id", courseId);
        //上移
        if (moveType.equals(1)) {
            qw.lt("order_no", orderNo);
        } else {
            //下移
            qw.gt("order_no", orderNo);
        }
        qw.orderByDesc("order_no");
        return this.selectFirst(qw);
    }

    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(CourseIndexRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        return qw;
    }
}
